package com.hspedu.common.utils;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author: xujiabing
 * @date: 2024/5/30 14:51
 * @description
 */
public class ImageDown {
    static Map map = new LinkedHashMap();
    private static Object obj = new Object();

    public static void main(String args[]) {
        /*
         * 这里我们创建6个线程（经测试，下载200多张图，每张大概20k，用时是最短的）。
         * 重复文件名会自动覆盖，所以不用考虑线程安全问题。
         * */
        new Thread(new ImageDown.downImage()).start();
        new Thread(new ImageDown.downImage()).start();
        new Thread(new ImageDown.downImage()).start();
        new Thread(new ImageDown.downImage()).start();
        new Thread(new ImageDown.downImage()).start();
        new Thread(new ImageDown.downImage()).start();
        new Thread(new ImageDown.downImage()).start();
        new Thread(new ImageDown.downImage()).start();
    }

    public static class downImage implements Runnable {

        @Override
        public void run() {
            long startTime = System.currentTimeMillis();
            try {
                FileReader file = new FileReader("D:\\DownloadImageSet\\image.txt");//获取文件流位置
                BufferedReader br = new BufferedReader(file);//构造一个BufferedReader类来读取文件
                String imgUrl, picName, document;
                // 使用readLine方法，一次读一行
                while ((document = br.readLine()) != null) {
                    //休眠解决只有一个线程运行
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    synchronized (obj){
                        //防止多线程重复读取相同url
                        if (map.get(document) != null){
                            continue;
                        }
                        //读取当前行截取字符作为图片名（前九个字符，根据实际情况自定制）
                        picName = document.substring(document.lastIndexOf("/"));
                        imgUrl = document.trim();
                        downImages("D:\\downloadImage\\", imgUrl, picName);//输出文件流位置“D:\\downloadImage\\”
                        map.put(document,document);
                        System.out.println(Thread.currentThread().getName() + "正在下载图片：" + picName);
                    }
                }
                br.close();

            } catch (Exception e) {
                e.printStackTrace();
                long endTime = System.currentTimeMillis();
                System.out.println("程序运行时间：" + (endTime - startTime) + "ms");
            }
        }

        private static void downImages(String filePath, String imgUrl, String picName) {
            File Dir = new File(filePath);//若存取文件夹没有，则先创建
            if (!Dir.exists()) {
                Dir.mkdirs();
            }
            // 获取当前线程
            //Thread currentThread = Thread.currentThread();

            File file = new File(filePath + picName);//写出路径
            InputStream inStream;

            try {
                URL url = new URL(imgUrl);// 构造URL
                URLConnection con = url.openConnection();// 打开连接
                inStream = con.getInputStream();
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();//中转站，现将图片数据放到outStream中
                byte[] buf = new byte[1024];
                int len;
                while ((len = inStream.read(buf)) != -1) {
                    outStream.write(buf, 0, len);
                }
                inStream.close();
                outStream.close();
                FileOutputStream op = new FileOutputStream(file);//图片下载的位置
                op.write(outStream.toByteArray());
                op.close();
                //System.out.println("图片"+ imgUrl +"下载完成" + "当前线程=" + currentThread.getName());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
